﻿using System;
using System.Collections.Generic;
using System.Text;
using System.Drawing;
using Vortex.Wrapper.Direct3D;
using Vortex.Wrapper;
using Vortex.Debugging;

namespace Vortex.Drawing {

	/// <summary>
	/// Defines a way of using z buffer by drawing target
	/// </summary>
	public enum DrawingTargetZUsage {
		/// <summary>Drawing target doesn't use Z-buffer at all.</summary>
		None,
		/// <summary>Drawing target uses shared Z-Buffer with orimary target</summary>
		Shared,
		/// <summary>Drawing target creates own Z-Buffer</summary>
		Own
	};

	/// <summary>
	/// AutoTargetTexture is designed for easier maintain of drawing target textures which should be of the same size as some other drawing target
	/// </summary>
	public class AutoTargetTexture : BaseTargetTexture, IDrawingTarget {
		IDrawingTarget _targetToMatch;

		/// <summary>
		/// Initializes a new instance of the <see cref="AutoTargetTexture"/> class. Usage mode of Z-Buffer is shared.
		/// </summary>
		/// <param name="targetToMatch">The target to match. Target can't be another instance of <see cref="AutoTargetTexture"/>.</param>
		public AutoTargetTexture(IDrawingTarget targetToMatch) 
			: this(targetToMatch, DrawingTargetZUsage.Shared) {

		}

		/// <summary>
		/// Initializes a new instance of the <see cref="AutoTargetTexture"/> class.
		/// </summary>
		/// <param name="targetToMatch">The target to match. Target can't be another instance of <see cref="AutoTargetTexture"/></param>
		/// <param name="usage">The usage type of z-buffer.</param>
		public AutoTargetTexture(IDrawingTarget targetToMatch, DrawingTargetZUsage usage) {
			if (null == targetToMatch) throw new ArgumentNullException("targetToMatch");
			if (targetToMatch is AutoTargetTexture) throw new Exception("AutoTargetTexture can be initialized with another AutoTargetTexture as target");

			_targetToMatch = targetToMatch;
			Size size = targetToMatch.Size;
			InitializeTargetTexture(size.Width, size.Height, targetToMatch.Format, usage == DrawingTargetZUsage.Own);

			//recreate surface
			_targetToMatch.OnResizeSurface += delegate(IDrawingTarget target) {
				FreeData();
				InitializeTargetTexture(target.Size.Width, target.Size.Height, targetToMatch.Format, usage == DrawingTargetZUsage.Own);
				//cascade surface resize event
				InvokeSurfaceResizeEvent();
			};

			_targetToMatch.OnCreateSurface += delegate(IDrawingTarget target) {
				//share z-buffer...
				if (usage == DrawingTargetZUsage.Shared) {
					_sharedZBuffer = target.TargetData.ZBuffer;
				}
			};

			_targetToMatch.OnDestroySurface += delegate(IDrawingTarget target) {
				//share z-buffer...
				if (usage == DrawingTargetZUsage.Shared) {
					_sharedZBuffer = null;
				}
			}; 
		}

	}
}
